#include "crossroad.hpp"
#include <bitset>
#include <iostream>

namespace jam {

Crossroad crossroad;

void Crossroad::schedule() {
  counter_t counter = 0;
  for (; ;) {
    /* 按北东西南的顺序检查路口是否有车 */
    #define SET_FLAG(dir, i) counter.set(i, QUEUE_FIELD(dir).has_car())
    ITERATE_NEWS_ARG(SET_FLAG, 3, 2, 1, 0);
    #undef SET_FLAG
    /* 根据路口车辆数目决策调度策略 */
    if (counter.all()) {
      dead_lock_scheduler();
    } else if (counter.none()) {
      happy_end_scheduler();
      break;
    } else {
      right_first_scheduler();
    }
  }
}

void Crossroad::add_cars(Directions &ds) {
  car_id_t car_id = 0;
  for (direction_t d : ds) {
    switch (d) {
      #define LAZY_CASE(dir) case dir: QUEUE_FIELD(dir).add_car(car_id++); break
      ITERATE_ESWN(LAZY_CASE);
      #undef LAZY_CASE
      CONTINUE_ON_UNDEF;
    }
  }
}

void inline Crossroad::dead_lock_scheduler() {
  /* 东南西北依次通行 */
  std::cout << "DEADLOCK: emit East..." << std::endl;
  #define EMIT(d) QUEUE_FIELD(d).emit()
  ITERATE_ESWN(EMIT);
  #undef EMIT
}

void inline Crossroad::right_first_scheduler() {
  /* 搜索最北(最优先通行)的位置 */
  direction_t start = Undefined;
  #define SEARCH(d) if(QUEUE_FIELD(d).has_car()) { start = d; goto pass; }
  ITERATE_NEWS(SEARCH);
  #undef SEARCH
pass:
  /* 依次通行 */
  switch (start) {
    #define LAZY_CASE(d) case d: iterate_clockwise<d, _tpl>(); break
    ITERATE_ENWS(LAZY_CASE);
    #undef LAZY_CASE
    default:
      break;
  }
}

void inline Crossroad::happy_end_scheduler() {
  std::cout << "[Scheduler]: Done." << std::endl;
}

}